package multi_thread.advanced;

/**
 * @author Cheng Jun
 * Description: InheritableThreadLocal 的应用场景 链路追踪、日志
 * @version 1.0
 * @date 2020/3/5 13:09
 * @see ThreadLocalExample
 * 深度copy 父线程的 inheritableThreadLocal，因为子线程有可能会修改本地线程变量，
 * 如果不是深度copy 就会影响父线程和 其它 copy 父线程 inheritableThreadLocal 的子代线程
 * @see ThreadLocal.ThreadLocalMap#ThreadLocalMap(java.lang.ThreadLocal.ThreadLocalMap)
 */
public class InheritableThreadLocalExample {

    // 子线程在构造函数里，从父线程 深度copy inheritableThreadLocals 变量，每个子线程都有独立的副本。
    // 子线程构造完成后，父线程的修改及其它子线程的修改，对这个子线程毫无影响。
    private static InheritableThreadLocal<String> inheritableThreadLocalStr = new InheritableThreadLocal<>();

    public static void main(String[] args) throws InterruptedException {
        inheritableThreadLocalStr.set(" 父线程数据");
        System.out.println(Thread.currentThread().getName() + inheritableThreadLocalStr.get());
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + inheritableThreadLocalStr.get());
            inheritableThreadLocalStr.set(inheritableThreadLocalStr.get() + "，在子线程修改了");
            System.out.println(Thread.currentThread().getName() + inheritableThreadLocalStr.get());
        }).start();

        // Thread thread = new Thread(() -> {
        //     System.out.println(Thread.currentThread().getName() + inheritableThreadLocalStr.get());
        //     inheritableThreadLocalStr.set(" ++++++" + inheritableThreadLocalStr.get());
        //     System.out.println(Thread.currentThread().getName() + inheritableThreadLocalStr.get());
        // });
        Thread.sleep(1000);
        System.out.println(Thread.currentThread().getName() + inheritableThreadLocalStr.get());
        // Thread.sleep(1000);
        // thread.start();
    }
}
